import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'dart:io';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '数据库测试',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: '数据库测试'),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  int _cnt = 0;
  String dbName = "test.db";
  String dbPath = "";
  String sql_createAccountTable = "create table account_table(id integer primary key, username text not null, password text not null)";
  List<Map> _items = [];

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
    var name = "user$_counter";
    var psd = "password";
    _add(name, psd);
  }

  Future<String> _createNewDb(String dbName) async {
    var dbPath = await getDatabasesPath();
    print("DBPath:" + dbPath);

    String path = join(dbPath, dbName);
    if (await new Directory(dirname(path)).exists()) {
      await deleteDatabase(path);
    }else {
      try {
        await new Directory(dirname(path)).create(recursive: true);
      } catch(e) {
        print(e);
      }
    }
    return path;
  }

  _create() async {
    dbPath = await _createNewDb(dbName);
    Database db = await openDatabase(dbPath);
    await db.execute(sql_createAccountTable);
    await db.close();
    print("创建数据库成功");
  }

  _open() async {
    if (null == dbPath) {
      var path = await getDatabasesPath();
      dbPath = join(path, dbName);
      print('dbPath:'+dbPath);
    }

    return await openDatabase(dbPath);
  }

  _add(String username, String password) async {
    Database db = await _open();
    String sql = "insert into account_table(username,password) values('$username', '$password')";
    await db.transaction((txn) async {
      int id = await txn.rawInsert(sql);
    });
    await db.close();
    print('插入数据成功');
    _refresh();
  }

  _delete(Map info) async {
    var id = info["id"];
    Database db = await _open();
    String sql = "DELETE FROM account_table where id = $id";
    await db.rawDelete(sql);
    await db.close();
    print('删除数据成功');
    _refresh();
  }

  _update(int id, String account, String pwd) async {
    Database db = await _open();
    String sql = "Update account_table set password = ?, username = ? where id = ?";
    int count = await db.rawUpdate(sql, [pwd, account, id]);
    await db.close();
    print('更新数据成功');
    _refresh();
  }

  _batch() async {
    Database db = await _open();
    var batch = db.batch();
    batch.insert("account_table", {"username":"123450002", "password":"111"});
    batch.update("account_table", {"username":"123450003"}, where: "username=?", whereArgs: ["123450002"]);
    batch.delete("account_table", where: "username=?", whereArgs: ["123450001"]);
    var results = await batch.commit();
    await db.close();
    print('批量修改成功');
    _refresh();
  }

  _queryNumber() async {
    Database db = await _open();
    int count = Sqflite.firstIntValue(await db.rawQuery("select COUNT(*) from account_table"));
    await db.close();
    print("查询数据成功 $count");
    setState(() {
      _cnt = count;
    });
  }

  Future<List> _query() async {
    Database db = await _open();
    List<Map> list = await db.rawQuery("select * from account_table");
    await db.close();
    print(list);
    return list;
  }


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _create();
  }


  Future _refresh() async {
    var list = await _query();
    _items = List.from(list);
    _queryNumber();
    setState(() {

    });
  }

  @override
  Widget build(BuildContext context) {
    final size =MediaQuery.of(context).size;
    final double topPadding = MediaQuery.of(context).padding.top;

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          new Container(
            padding: EdgeInsets.only(top: topPadding, right: 15),
            child: new Text(_cnt.toString()),
          )
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Expanded(
                child: new Container(
                  height: 100,
                  width: size.width,
                  child: new RefreshIndicator(
                      child: new ListView.builder(
                        itemCount: _items.length,
                        itemExtent: 44,
                        itemBuilder: (context, index) {
                          return Dismissible(
                              onDismissed: (direction) {
                                _delete(_items[index]);
                              },
                              movementDuration: Duration(milliseconds: 100),
                              key: Key(UniqueKey().toString()),
                              child: new Container(
                                child: new FlatButton(
                                    onPressed: () {
                                      showDialog<Null>(
                                          context: context, //BuildContext对象
                                          barrierDismissible: false,
                                          builder: (BuildContext context) {
                                            return new AccountDialog( //调用对话框
                                              title: '标题',
                                              accountValue: _items[index]["username"],
                                              passwordValue: _items[index]["password"],
                                              onEnsureEvent: (account, password) {
                                                _update(_items[index]["id"], account, password);
                                                Navigator.pop(context);
                                              },
                                            );
                                          });
                                    },
                                    child: UserCell(_items[index])
                                ),
                                decoration: BoxDecoration(
                                    border: Border(bottom: BorderSide(width: 1, color: Color(0xFFF2F2F2)))
                                ),
                              ),
                              background: Container(
                                  color: Color(0xffff0000),
                              ),
                          );
                        },
                        physics: const AlwaysScrollableScrollPhysics(),
                      ),
                      onRefresh: _refresh
                  ),
                )
            ),
            new FlatButton(
                onPressed: _batch,
                child: new Container(
                  color: Colors.orange,
                  width: size.width,
                  height: 44,
                  alignment: Alignment.center,
                  child: new Text('批量操作按钮', textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontSize: 20),),
                )
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class UserCell extends StatefulWidget {
  var userInfo;
  UserCell(this.userInfo);
  @override
  State<StatefulWidget> createState() {
    return _UserCellState(userInfo);
  }
}

class _UserCellState extends State<UserCell> {
  var userInfo;
  _UserCellState(this.userInfo);
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Container(
      child: new Row(
        children: <Widget>[
          new Container(
            margin: EdgeInsets.only(right: 10),
            child: new Text(userInfo["id"].toString(), style: TextStyle(color: Colors.red),),
          ),
          new Container(
            margin: EdgeInsets.only(right: 10),
            child: new Text(userInfo["username"], style: TextStyle(color: Colors.blue),),
          ),
          new Text(userInfo["password"], style: TextStyle(color: Colors.green),),
        ],
      ),
    );
  }
}

class AccountDialog extends Dialog {
  String title;
  String accountValue;
  String passwordValue;
  Function onEnsureEvent;
  var _account = new TextEditingController();
  var _password = new TextEditingController();

  AccountDialog({
    Key key,
    this.title,
    this.accountValue,
    this.passwordValue,
    this.onEnsureEvent
  }) : super(key: key);


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    _account.value = new TextEditingValue(
        text: accountValue ?? "",
    );
    _password.value = new TextEditingValue(
        text: passwordValue ?? "",
    );
    //        selection: TextSelection.fromPosition(TextPosition(affinity: TextAffinity.downstream, offset: passwordValue.length))
    return new Padding(
        padding: const EdgeInsets.all(15.0),
        child: new Material(
          type: MaterialType.transparency,
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Container(
                decoration: ShapeDecoration(
                  color: Color(0xffffffff),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(8.0),
                    ),
                  ),
                ),
                margin: const EdgeInsets.all(12.0),
                child: new Container(
                  child: new Column(
                    children: <Widget>[
                      new Padding(
                        padding: const EdgeInsets.all(10.0),
                        child: new Stack(
                          alignment: AlignmentDirectional.centerEnd,
                          children: <Widget>[
                            new Center(
                              child: new Text(
                                title,
                                style: new TextStyle(
                                  fontSize: 19.0,
                                ),
                              ),
                            ),
                            new GestureDetector(
                              onTap: () {
                                Navigator.pop(context);
                              },
                              child: new Padding(
                                padding: const EdgeInsets.all(5.0),
                                child: new Icon(
                                  Icons.close,
                                  color: Color(0xffe0e0e0),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                      new Container(
                        color: Color(0xffe0e0e0),
                        height: 1.0,
                      ),
                      new Container(
                        padding: const EdgeInsets.only(left: 10.0, right: 10.0),
                        child: new TextField(
                          decoration: InputDecoration(
                            hintText: '请输入账号',
                            border: InputBorder.none,
                          ),
                          controller: _account,
                          onChanged: (value) {
                            accountValue = value;
                          },
                        ),
                      ),
                      new Container(
                        color: Color(0xffe0e0e0),
                        height: 1.0,
                      ),
                      new Container(
                        padding: const EdgeInsets.only(left: 10.0, right: 10.0),
                        child: new TextField(
                          decoration: InputDecoration(
                            hintText: '请输入密码',
                            border: InputBorder.none,
                          ),
                          controller: _password,
                          onChanged: (value) {
                            passwordValue = value;
                          },
                        ),
                      ),
                      new Container(
                        color: Color(0xffe0e0e0),
                        height: 1.0,
                      ),
                      new ClipRRect(
                        borderRadius: BorderRadius.circular(12),
                        child: new Container(
                          color: Colors.orange,
                          margin: const EdgeInsets.only(top: 5.0, bottom: 5.0),
                          child: new FlatButton(
                              onPressed: () {
                                this.onEnsureEvent(_account.text, _password.text);
                              },
                              child: new Text('确认', style: TextStyle(color: Colors.white, fontSize: 18),)
                          ),
                        ),
                      )
                    ],
                  )
                ),
              )
            ],
          ),
        ),
    );
  }
}

// ignore: must_be_immutable
class MessageDialog extends Dialog {
  String title;
  String message;
  String negativeText;
  String positiveText;
  Function onCloseEvent;
  Function onPositivePressEvent;

  MessageDialog({
    Key key,
    @required this.title,
    @required this.message,
    this.negativeText,
    this.positiveText,
    this.onPositivePressEvent,
    @required this.onCloseEvent,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Padding(
      padding: const EdgeInsets.all(15.0),
      child: new Material(
        type: MaterialType.transparency,
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Container(
              decoration: ShapeDecoration(
                color: Color(0xffffffff),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(
                    Radius.circular(8.0),
                  ),
                ),
              ),
              margin: const EdgeInsets.all(12.0),
              child: new Column(
                children: <Widget>[
                  new Padding(
                    padding: const EdgeInsets.all(10.0),
                    child: new Stack(
                      alignment: AlignmentDirectional.centerEnd,
                      children: <Widget>[
                        new Center(
                          child: new Text(
                            title,
                            style: new TextStyle(
                              fontSize: 19.0,
                            ),
                          ),
                        ),
                        new GestureDetector(
                          onTap: this.onCloseEvent,
                          child: new Padding(
                            padding: const EdgeInsets.all(5.0),
                            child: new Icon(
                              Icons.close,
                              color: Color(0xffe0e0e0),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                  new Container(
                    color: Color(0xffe0e0e0),
                    height: 1.0,
                  ),
                  new Container(
                    constraints: BoxConstraints(minHeight: 180.0),
                    child: new Padding(
                      padding: const EdgeInsets.all(12.0),
                      child: new IntrinsicHeight(
                        child: new Text(
                          message,
                          style: TextStyle(fontSize: 16.0),
                        ),
                      ),
                    ),
                  ),
                  this._buildBottomButtonGroup(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBottomButtonGroup() {
    var widgets = <Widget>[];
    if (negativeText != null && negativeText.isNotEmpty) widgets.add(_buildBottomCancelButton());
    if (positiveText != null && positiveText.isNotEmpty) widgets.add(_buildBottomPositiveButton());
    return new Flex(
      direction: Axis.horizontal,
      children: widgets,
    );
  }

  Widget _buildBottomCancelButton() {
    return new Flexible(
      fit: FlexFit.tight,
      child: new FlatButton(
        onPressed: onCloseEvent,
        child: new Text(
          negativeText,
          style: TextStyle(
            fontSize: 16.0,
          ),
        ),
      ),
    );
  }

  Widget _buildBottomPositiveButton() {
    return new Flexible(
      fit: FlexFit.tight,
      child: new FlatButton(
        onPressed: onPositivePressEvent,
        child: new Text(
          positiveText,
          style: TextStyle(
            color: Color(Colors.teal.value),
            fontSize: 16.0,
          ),
        ),
      ),
    );
  }
}